from flask import Flask, render_template, request, jsonify, send_file, session
import os
import sqlite3
import json
import shutil
import hashlib
from datetime import datetime
import uuid

app = Flask(__name__)
app.secret_key = 'your-secret-key-here'

# 初始化数据库
def init_db():
    conn = sqlite3.connect('repository.db')
    c = conn.cursor()
    
    # 仓库表
    c.execute('''CREATE TABLE IF NOT EXISTS repositories
                 (id TEXT PRIMARY KEY, name TEXT, description TEXT, 
                  visibility TEXT, owner TEXT, created_at TIMESTAMP)''')
    
    # 文件版本表
    c.execute('''CREATE TABLE IF NOT EXISTS file_versions
                 (id TEXT PRIMARY KEY, repo_id TEXT, file_path TEXT, 
                  file_hash TEXT, version INTEGER, author TEXT, 
                  message TEXT, created_at TIMESTAMP)''')
    
    # 成员权限表
    c.execute('''CREATE TABLE IF NOT EXISTS members
                 (id INTEGER PRIMARY KEY AUTOINCREMENT, repo_id TEXT, 
                  username TEXT, permission TEXT, joined_at TIMESTAMP)''')
    
    conn.commit()
    conn.close()

# 获取数据库连接
def get_db():
    conn = sqlite3.connect('repository.db')
    conn.row_factory = sqlite3.Row
    return conn

# 首页
@app.route('/')
def index():
    return render_template('index.html')

# 获取仓库列表
@app.route('/api/repositories')
def get_repositories():
    conn = get_db()
    repos = conn.execute('SELECT * FROM repositories ORDER BY created_at DESC').fetchall()
    conn.close()
    return jsonify([dict(repo) for repo in repos])

# 创建仓库
@app.route('/api/repositories', methods=['POST'])
def create_repository():
    data = request.json
    repo_id = str(uuid.uuid4())
    
    conn = get_db()
    conn.execute('''INSERT INTO repositories 
                   (id, name, description, visibility, owner, created_at)
                   VALUES (?, ?, ?, ?, ?, ?)''',
                (repo_id, data['name'], data['description'], 
                 data['visibility'], data.get('owner', 'admin'), datetime.now()))
    conn.commit()
    conn.close()
    
    # 创建仓库目录
    os.makedirs(f'repositories/{repo_id}', exist_ok=True)
    
    return jsonify({'id': repo_id, 'message': 'Repository created successfully'})

# 获取仓库文件
@app.route('/api/repositories/<repo_id>/files')
def get_files(repo_id):
    repo_path = f'repositories/{repo_id}'
    if not os.path.exists(repo_path):
        return jsonify({'error': 'Repository not found'}), 404
    
    files = []
    for root, dirs, filenames in os.walk(repo_path):
        for filename in filenames:
            file_path = os.path.join(root, filename)
            rel_path = os.path.relpath(file_path, repo_path)
            stat = os.stat(file_path)
            files.append({
                'name': filename,
                'path': rel_path,
                'size': stat.st_size,
                'modified': datetime.fromtimestamp(stat.st_mtime).isoformat()
            })
    
    return jsonify(files)

# 上传文件
@app.route('/api/repositories/<repo_id>/upload', methods=['POST'])
def upload_file(repo_id):
    if 'file' not in request.files:
        return jsonify({'error': 'No file provided'}), 400
    
    file = request.files['file']
    if file.filename == '':
        return jsonify({'error': 'No file selected'}), 400
    
    repo_path = f'repositories/{repo_id}'
    if not os.path.exists(repo_path):
        return jsonify({'error': 'Repository not found'}), 404
    
    # 保存文件
    file_path = os.path.join(repo_path, file.filename)
    file.save(file_path)
    
    # 计算文件哈希
    with open(file_path, 'rb') as f:
        file_hash = hashlib.sha256(f.read()).hexdigest()
    
    # 记录版本
    conn = get_db()
    version_id = str(uuid.uuid4())
    conn.execute('''INSERT INTO file_versions 
                   (id, repo_id, file_path, file_hash, version, author, message, created_at)
                   VALUES (?, ?, ?, ?, ?, ?, ?, ?)''',
                (version_id, repo_id, file.filename, file_hash, 1, 
                 'admin', 'Initial upload', datetime.now()))
    conn.commit()
    conn.close()
    
    return jsonify({'message': 'File uploaded successfully'})

# 下载文件
@app.route('/api/repositories/<repo_id>/download/<path:filename>')
def download_file(repo_id, filename):
    repo_path = f'repositories/{repo_id}'
    file_path = os.path.join(repo_path, filename)
    
    if not os.path.exists(file_path):
        return jsonify({'error': 'File not found'}), 404
    
    return send_file(file_path, as_attachment=True)

# 删除文件
@app.route('/api/repositories/<repo_id>/files/<path:filename>', methods=['DELETE'])
def delete_file(repo_id, filename):
    repo_path = f'repositories/{repo_id}'
    file_path = os.path.join(repo_path, filename)
    
    if not os.path.exists(file_path):
        return jsonify({'error': 'File not found'}), 404
    
    os.remove(file_path)
    
    # 记录删除操作
    conn = get_db()
    version_id = str(uuid.uuid4())
    conn.execute('''INSERT INTO file_versions 
                   (id, repo_id, file_path, file_hash, version, author, message, created_at)
                   VALUES (?, ?, ?, ?, ?, ?, ?, ?)''',
                (version_id, repo_id, filename, '', -1, 
                 'admin', f'Deleted {filename}', datetime.now()))
    conn.commit()
    conn.close()
    
    return jsonify({'message': 'File deleted successfully'})

# 获取版本历史
@app.route('/api/repositories/<repo_id>/history/<path:filename>')
def get_file_history(repo_id, filename):
    conn = get_db()
    history = conn.execute('''SELECT * FROM file_versions 
                             WHERE repo_id = ? AND file_path = ?
                             ORDER BY created_at DESC''',
                          (repo_id, filename)).fetchall()
    conn.close()
    return jsonify([dict(h) for h in history])

# 获取仓库成员
@app.route('/api/repositories/<repo_id>/members')
def get_members(repo_id):
    conn = get_db()
    members = conn.execute('SELECT * FROM members WHERE repo_id = ?', (repo_id,)).fetchall()
    conn.close()
    return jsonify([dict(m) for m in members])

# 添加成员
@app.route('/api/repositories/<repo_id>/members', methods=['POST'])
def add_member(repo_id):
    data = request.json
    
    conn = get_db()
    conn.execute('''INSERT INTO members (repo_id, username, permission, joined_at)
                   VALUES (?, ?, ?, ?)''',
                (repo_id, data['username'], data['permission'], datetime.now()))
    conn.commit()
    conn.close()
    
    return jsonify({'message': 'Member added successfully'})

if __name__ == '__main__':
    init_db()
    app.run(debug=True, host='0.0.0.0', port=5000)
